#include "BootLoader.h"

/**
  * @brief  跳转并执行到APP程序
  * @param  APPProgramAddr : APP程序的地址
  * @retval None
  */
void Jump_to_APP(uint32_t APPProgramAddr)
{
    Run_APP_t run_app = (Run_APP_t)(*(uint32_t*)(APPProgramAddr + 4));

    /* 检查堆栈地址(RAM地址)是否有效，然后跳转到用户应用程序 */
	/* 检查堆栈地址是否有效，单片机的RAM大小为0x10000，0x3000 0000 - 0x10000 = 0x2FFF 0000 */
    if((*(uint32_t*)APPProgramAddr & 0x2FFF0000) == 0x20000000)
    {
        /* 
           关闭所有中断，
           在它被置 1 后，就关掉所有可屏蔽的异常，只剩下NMI 和硬 fault 可以响应。
           它的缺省值是 0，表示没有关中断。
        */
        __set_PRIMASK(1);

        /* 复位所有已经开启的外设 */
//        GPIO_DeInit(GPIOH);
//        GPIO_DeInit(GPIOA);
//        GPIO_DeInit(GPIOC);
//        EXTI_DeInit();
//        CRC_ResetDR();
//        USART_DeInit(USART1);

        /* 设置堆栈指针 */
//        __set_PSP(*(uint32_t*)APPProgramAddr);
//        __set_CONTROL(0);
        __set_MSP(*(uint32_t*)APPProgramAddr);

        /* 跳转到APP程序中执行 */
        run_app();
    }
    else
    {
//        Printf("BOOT_ERROR1!\r\n");
    }
}
void NVIC_SetVectorTable(uint32_t JUMP_APP_ADDR)
{
	uint32_t Temp_JUMP_APP_ADDR = JUMP_APP_ADDR;
	SCB->VTOR = FLASH_BASE | Temp_JUMP_APP_ADDR;
	__set_PRIMASK(0);
}
